﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Windows.Controls;
using BTM_Client_Library;
using Client_Server_Interface;
using BTM_Client_DBwork;

namespace BTM_Client_Application.SupportClasses
{
    /// <summary>
    /// Содержит информацию, которая необходима на протяжении всего времени работы приложения.
    /// </summary>
    public static class AliveInfo
    {
        const string READY_STATUS = "Ready";

        public delegate void ChangeDeviceOpenedStateDelegate(DeviceTreeItem.DeviceInfo deviceInfo, bool opened);

        public delegate void StatusUpdateDelegate(string status);

        /// <summary>
        /// Генерируется при изменении статуса приложения (Самая старая ошибка в списке или "ОК").
        /// </summary>
        public static event StatusUpdateDelegate StatusUpdateEvent;

        private static void OnStatusUpdateEvent(string status)
        {
            StatusUpdateDelegate handler = StatusUpdateEvent;
            if (handler != null) handler(status);
        }
        
        /// <summary>
        /// Генерируется при потере связи с сервером.
        /// </summary>
        public static event VoidDelegate ServerDisconnectEvent;

        public static void OnServerDisconnectEvent()
        {
            VoidDelegate handler = ServerDisconnectEvent;
            if (handler != null) handler();
        }

        public delegate void IntValueDelegate(int count);

        /// <summary>
        /// Генерируется при изменении общего количества непрочитанных сообщений.
        /// </summary>
        public static event IntValueDelegate UnreadRecordsCountChangedEvent;

        private static void OnUnreadRecordsCountChangedEvent(int count)
        {
            IntValueDelegate handler = UnreadRecordsCountChangedEvent;
            if (handler != null) handler(count);
        }

        static AliveInfo()
        {
            CurrentCulture = new CultureInfo("ru");
            DeviceTree = new DeviceTree("nope");
            StatusList = new List<string>();
            MegaDeviceTree = new MegaDeviceTree();
            UnreadRecordsCount = 0;
            //ClientEvents = ClientEventsControl.CreateControl();
        }
        /// <summary>
        /// Культура приложения.
        /// </summary>
        public static CultureInfo CurrentCulture { get; set; }
        /// <summary>
        /// Дерево со всеми устройствами.
        /// </summary>
        public static DeviceTree DeviceTree { get; set; }

        public static string Login { get; set; }
        public static string Password { get; set; }
        public static byte[] ClientId { get; set; }

        public static void SetLoginData(string login, string password, byte[] clientId)
        {
            Login = login;
            Password = password;
            ClientId = clientId;
        }

        private static readonly string _curDir = Directory.GetCurrentDirectory();

        public static string CurDir
        {
            get { return _curDir; }
        }

        public static MainWindow MainWindow { get; set; }
        public static MegaDeviceTree MegaDeviceTree { get; set; }
        public static DeviceWorker DeviceWorker { get; set; }
        public static DBwork DBwork { get; set; }
        public static ClientHelper ClientHelper { get; set; }
        public static ChatClient Chat { get; set; }
        public static List<string> StatusList { get; private set; }
        private static string _curStatus = READY_STATUS;
        private static int _unreadRecordsCount;

        public static int UnreadRecordsCount
        {
            get { return _unreadRecordsCount; }
            set
            {
                OnUnreadRecordsCountChangedEvent(value);
                _unreadRecordsCount = value;
            }
        }
        
        private static void SetStatus(string status = "")
        {
            if (status == "")
            {
                status = StatusList.Count < 1 ? READY_STATUS : StatusList[0];
            }

            if (_curStatus != status)
            {
                OnStatusUpdateEvent(status);
                _curStatus = status;
            }
        }

        /// <summary>
        /// Добавление новой записи в массив с информацией (статусов). 
        /// Отображается самый старый. Если вставить READY_STATUS, список ошибок очиститься.
        /// </summary>
        /// <param name="newStatus">Добавляемый статус.</param>
        public static void AddStatus(string newStatus)
        {
            if (newStatus == READY_STATUS)
            {
                StatusList.Clear();
                SetStatus(READY_STATUS);
                return;
            }
            if (_curStatus == READY_STATUS)
            {
                SetStatus(newStatus);
            }
            if(!StatusList.Contains(newStatus))
                StatusList.Add(newStatus);
        }

        /// <summary>
        /// Удаление записи из массива статусов. Когда список станет пуст,
        /// текущий статус изменится на READY_STATUS
        /// </summary>
        /// <param name="remStatus">Удаляемый статус.</param>
        public static void RemoveStatus(string remStatus)
        {
            if (StatusList.Contains(remStatus))
                StatusList.Remove(remStatus);
            SetStatus();
        }
        
        /// <summary>
        /// Возвращает самую старую запись в списке статусов.
        /// </summary>
        public static string Status { get { return _curStatus; } }

        public static void ResetStatusUpdateEvent()
        {
            StatusUpdateEvent = null;
        }

        public static ChangeDeviceOpenedStateDelegate ChangeDeviceOpenedState { get; set; }

        public static void CreateEventControl(Button but)
        {
            ClientEvents = ClientEventsControl.CreateControl(but);
        }

        public static ClientEventsControl ClientEvents { get; set; }

        public static MapControl.SetMapPositionDelegate SetMapPosition { get; set; }
    }
}
